<?php

namespace App\Http\Controllers\Api;


use App\Library\OSS;
use App\Modules\Good\Models\Good;
use App\Modules\Package\Models\GoodPackage;
use App\Modules\Shop\GoodsList;
use App\Modules\Shop\Manager;
use App\Modules\Shop\Models\Banner;
use App\Modules\Shop\Models\Category;
use App\Modules\Shop\Shop;
use App\Modules\Shop\ShopRecommend;
use App\Modules\System\Models\Brand;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use test\Mockery\Fixtures\MethodWithVoidReturnType;
use Overtrue\LaravelWeChat\Facade as EasyWeChat;
use App\Modules\Comment\Models\Comment;

class ShopController extends ApiController
{
    public function getShopList(Request $request)
    {
        $this->validate($request, [
            'category'       => 'nullable|string',
            'offset'         => 'nullable|integer',
            'count'          => 'nullable|integer',
            'is_photography' => 'nullable|boolean',
            'sort'           => 'nullable|string',
            'search'         => 'nullable|string',
        ]);

        $offset        = $request->input('offset', 0);
        $count         = $request->input('count', 10);
        $isPhotography = $request->input('is_photography');
        $sort          = $request->input('sort');
        $search        = $request->input('search');
        $category      = $request->input('category');
        $longitude1    = $request->input('longitude');//用户经度
        $latitude1     = $request->input('latitude');//用户纬度

        $query = Shop::query()
            ->where('status', Shop::STATUS_OPEN)
            ->offset($offset)
            ->limit($count);
        if (!is_null($isPhotography)) {
            $query->where('type', Shop::TYPE_PHOTO);
        }
        if (!is_null($category)) {
            $query->whereJsonContains('category', $category);
        }
        switch ($sort) {
            case 'popularity':// 口碑
                $query->orderBy('visitor', 'desc')
                      ->orderBy('created_at', 'desc');
                break;
            case 'good'://商品数量
                $query->orderBy('goods_number', 'desc')
                      ->orderBy('created_at', 'desc');
                break;
            case 'multiple':
                $query
                    ->orderBy('visitor', 'desc')
                    ->orderBy('created_at', 'desc');
                break;
            case 'distance':
                $query->selectRaw('*,(st_distance(point(longitude,latitude),point('.$longitude1.','.$latitude1.'))*111195 ) as distance_range')
                      ->orderBy('distance_range', 'asc');
            default:
                $query->orderBy('sort', 'desc')
                      ->orderBy('created_at', 'desc');
                break;
        }
        if (!is_null($search)) {
            $query->where('name', 'like', "%".$search."%");
        }
        $re = $query->get();
        $count = GoodPackage::query()
            ->whereIn('shop_id', $re->pluck('id')->all())
            ->where('status', GoodPackage::STATUS_ON)
            ->selectRaw('count(1) as count, shop_id')
            ->groupBy('shop_id')
            ->get()
            ->pluck('count', 'shop_id');
        $re->each(function ($item) use($count,$longitude1,$latitude1) {
            $item->package_number = $count->get($item->id)??0;
            $item->cover = OSS::instance()->getUrl($item->cover);

            if ($item->longitude && $item->latitude) {
                $item->distance = $this->getDistance($longitude1, $latitude1, $item->longitude, $item->latitude);
            }else{
                $item->distance = '';
            }

            return $item;
        });

        return $this->success($re);
    }

    /**
     * 计算两点地理坐标之间的距离
     * @param Decimal $longitude1 起点经度
     * @param Decimal $latitude1 起点纬度
     * @param Decimal $longitude2 终点经度
     * @param Decimal $latitude2 终点纬度
     * @param Int   $unit    单位 1:米 2:公里
     * @param Int   $decimal  精度 保留小数位数
     * @return Decimal
     */
    private function getDistance($longitude1=0, $latitude1=0, $longitude2=0, $latitude2=0, $unit=2, $decimal=2){

        $earth_radius = 6370.996; // 地球半径系数
        $pi = 3.1415926;

        $radLat1 = $latitude1 * $pi / 180.0;
        $radLat2 = $latitude2 * $pi / 180.0;

        $radLng1 = $longitude1 * $pi / 180.0;
        $radLng2 = $longitude2 * $pi / 180.0;

        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;

        $distance = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
        $distance = $distance * $earth_radius * 1000;

        if($unit==2){
            $distance = $distance / 1000;
        }

        return round($distance, $decimal);

    }

    public function detail(Request $request)
    {
        $this->validate($request, [
            'id' => 'integer',
        ]);
        $id = $request->input('id');
        $shop = Shop::query()->find($id);
        if (is_null($shop)) {
            return $this->fail('店铺id错误');
        }
        $shop->cover = empty($shop->cover) ? "" : OSS::instance()->getUrl($shop->cover);
        $count = GoodPackage::query()
            ->where('shop_id', $id)
            ->where('status', GoodPackage::STATUS_ON)
            ->count();
        $shop->package_number = $count;
        return $this->success($shop);
    }

    public function getBanner(Request $request)
    {
        $this->validate($request, [
            'shop_id' => 'required|integer',
        ]);
        $shopId = $request->input('shop_id');
        $shop = Banner::query()
            ->where('type', Banner::TYPE_SHOP)
            ->where('shop_id', $shopId)
            ->get()
            ->map(function ($item) {
                $item->image = OSS::instance()->getUrl($item->image);
                return $item;
            });

        return $this->success($shop);
    }

    public function visitor(Request $request)
    {
        $this->validate($request, [
            'id' => 'required|id',
        ]);
        $id = $request->input('id');
        Shop::query()
            ->where('id', $id)
            ->increment('visitor');
        return $this->success();
    }

    public function sample(Request $request)
    {
        $this->validate($request, [
            'shop_id' => 'required|integer'
        ]);
        $shopId = $request->input('shop_id');
        $package = GoodPackage::query()
            ->where('shop_id', $shopId)
            ->where('status', GoodPackage::STATUS_ON)
            ->orderBy('sort', 'desc')
            ->get()
            ->map(function ($item) {
                $cover = [];
                $hotCover = null;
                $recommendCover = null;
                $selectedCover = null;
                if (!empty($item->hot_cover)) {
                    $hotCover = OSS::instance()->getUrl($item->hot_cover);
                }
                if (!empty($item->recommend_cover)) {
                    $recommendCover = OSS::instance()->getUrl($item->recommend_cover);
                }
                if (!empty($item->selected_cover)) {
                    $selectedCover = OSS::instance()->getUrl($item->selected_cover);
                }
                foreach ($item->cover as $tmp) {
                    $cover[] = OSS::instance()->getUrl($tmp);
                }
                return [
                    'id'              => $item->id,
                    'name'            => $item->name,
                    'cover'           => $cover,
                    'hot_cover'       => $hotCover,
                    'recommend_cover' => $recommendCover,
                    'selected_cover'  => $selectedCover,
                    'display_price'   => $item->display_price,
                    'price'           => $item->price,
                    'sales_volume'    => $item->sales_volume,
                    'share_number'    => $item->share_number,
                    'visitor'         => $item->visitor,
                ];
            });
        return $this->success($package);
    }

    public function getGoodsList(Request $request)
    {
        $this->validate($request, [
            'offset' => 'nullable|integer',
            'count'  => 'nullable|integer',
            'sort'   => 'nullable|string',
            'screen' => 'nullable|array',
        ]);
        $offset = $request->input('offset', 0);
        $count  = $request->input('count', 10);
        $sort   = $request->input('sort');
        $screen = $request->input('screen');

        $query = GoodsList::query()
            ->offset($offset)
            ->limit($count);
        if (isset($screen['min']) && !empty($screen['min'])) {
            $query->where('price', ">=", $screen['min']);
        }
        if (isset($screen['max']) && !empty($screen['max'])) {
            $query->where('price', "<=", $screen['max']);
        }

        switch ($sort) {
            case "createdAt":
                $query->orderByDesc('time');
                break;
            case "priceDesc":
                $query->orderByDesc('price');
                break;
            case "priceAsc":
                $query->orderBy('price', 'asc');
                break;
            case "salesVolume":
                $query->orderBy('sales_volume', 'asc');
                break;
            case "visitor":
                $query->orderBy('visitor', 'desc');
                break;
        }
        $query->orderBy('sort', 'desc');
        $data = $query->get();
        $tmp = $data->groupBy('goods_type');

        $package = GoodPackage::query()->find($tmp->get(GoodsList::TYPE_PACKAGE)->pluck('link_id')->all())->keyBy('id');
        $goods = Good::query()->find($tmp->get(GoodsList::TYPE_GOOD)->pluck('link_id')->all())->keyBy('id');
        $re = $data->map(function ($item) use($package, $goods) {
                $tmp = null;
                if ($item->goods_type == GoodsList::TYPE_PACKAGE) {
                    $tmp = $package->get($item->link_id);
                } else {
                    $tmp = $goods->get($item->link_id);
                }

                $cover = [];
                foreach ($tmp->cover as $value) {
                    $cover = OSS::instance()->getUrl($value);
                }
                return [
                    'id'            => $tmp->id,
                    'type'          => $item->goods_type,
                    'name'          => $tmp->name,
                    'visitor'       => $tmp->visitor,
                    'share_number'  => $tmp->share_number,
                    'cover'         => $cover,
                    'display_price' => $tmp->display_price??null,
                    'price'         => $tmp->price,
                    'stock'         => $tmp->stock??null,
                    'sales_volume'  => $tmp->sales_volume??0,
                    'is_free'       => $tmp->is_free,
                ];
            });
        return $this->success($re);
    }

    public function getRecommend(Request $request)
    {
        $this->validate($request, [
            'shop_id' => 'required|integer',
        ]);
        $shopId = $request->input('shop_id');

        $shop = Shop::query()->find($shopId);
        $recommend = ShopRecommend::query()
            ->where('shop_id', $shopId)
            ->get();

        if ($shop->type == Shop::TYPE_PHOTO) {
            $query = GoodPackage::query()
                ->where('shop_id', $shopId);
        } else {
            $query = Good::query()
                ->where('shop_id', $shopId);
        }
        $re = $query
            ->whereIn('id', $recommend->pluck('link_id')->all())
            ->where('status', Good::STATUE_ON)
            ->get()
            ->map(function ($item) {
                $cover = [];
                foreach ($item->cover as $value) {
                    $cover = OSS::instance()->getUrl($value);
                }
                $recommendCover = null;
                if (!empty($item->recommend_cover)) {
                    $recommendCover = OSS::instance()->getUrl($item->recommend_cover);
                }
                return [
                    'id'              => $item->id,
                    'name'            => $item->name,
                    'recommend_cover' => $recommendCover,
                    'cover'           => $cover,
                    'display_price'   => $item->display_price,
                    'price'           => $item->price,
                ];
            });
        return $this->success($re);
    }

    public function getCategory(Request $request)
    {
        $this->validate($request, [
            'type' => 'required|string',
        ]);
        $type = $request->input('type');
        $re = Category::query()
            ->where('parent', $type)
            ->orderBy('sort', 'desc')
            ->get()
            ->map(function ($item) {
                return [
                    'id' => $item->id,
                    'name' => $item->name,
                ];
            });
        return $this->success($re);
    }

    /**
     * 获取筛选参数
     */
    public function getParams(Request $request){
        $this->validate($request, [
            'shop_id' => 'required|integer',//门店id
        ]);

        $aParams = [];
        $iShopId = $request->input('shop_id');
        $shopData = Shop::query()->find($iShopId);
        $topCategory = $shopData->category;
        $topCategoryId = $shopData->category_ids;

        $categoryData = Category::query()
                        ->where('shop_id', $iShopId)
                        ->where('deleted_at', null)
                        ->get()->toArray();

        $aSpec = [];
        if (!empty($topCategoryId)) {
            foreach ($topCategoryId as $k => $v) {
               $tmp = [];
                foreach ($categoryData as $k1 => $v1) {
                    if ($v1['first_category_id'] != 0) {
                        $aSpec['title'] = '规格与功能';
                        $aSpec['field'] = 'category_id';
                        $v1['flag'] = '';
                        $aSpec['data'][$v1['name']] = $v1;
                    }
                    if ($v1['top_category_id'] == $v && $v1['first_category_id'] == 0) {
                        $tmp['title'] = $topCategory[$k];
                        $tmp['top_category_id'] = $topCategoryId[$k];
                        $tmp['field'] = 'first_category_id';
                        $tmp['data'][$v1['name']] = $v1;
                        // $tmp['data'][] = $v1;
                    }
                }

                $aParams[] = $tmp;
            }
        }
        $aParams[] = $aSpec;
        
        //获取品牌
        $brand = Brand::query()->where('shop_id', $iShopId)->get(['id','name'])->toArray();
        $brandData = [];
        if (!empty($brand)) {
            foreach ($brand as $key => $value) {
                $brandData[$value['name']] = [
                    'id'     => $value['id'],
                    'name'   => $value['name'],
                    // 'parent' => $value['parent'],
                    // 'pid'    => $value['pid'],
                    // 'sort'   => $value['sort'],
                ];
            }
        }

        $aParams[] = [
            'title' => '品牌',
            'field' => 'brand_id',
            'data'  => $brandData,
        ];
        
        return $this->success($aParams);
    }

    /**
     * 商家回复评论
     */
    public function reply(Request $request)
    {
        $this->validate($request, [
            'pid'     => 'required|integer',//评论id
            'content' => 'nullable|string',
        ]);

        $user = $this->getUser();
        $name = $user->name . '(' . $user->nickname . ')';
        $pid     = $request->input('pid');
        $content = $request->input('content');
        // if (!empty($content)) {
        //     $app = EasyWeChat::miniProgram();
        //     $result = $app->content_security->checkText($content);
        //     if ($result['errcode'] != 0) {
        //         return $this->fail("发布内容包含敏感词");
        //     }
        // }
        $comment = Comment::query()
            ->create([
                'user_id' => 0,
                'link_id' => 0,
                'type'    => '',
                'score'   => 0,
                'pid'     => $pid,
                'content' => $content,
                'merchant_reply_username' => $name,
            ]);

        return $this->success();
    }

    /**
     * 查看商家评论
     */
    public function getComment(Request $request)
    {

        /**
         * 评论表 shop_id 修改
         */
//         $aGood = DB::table('comments')->where('type', 'good')->get(['id','link_id']);
//         $aPackage = DB::table('comments')->where('type', 'package')->get(['id','link_id']);
//         foreach ($aGood as $v1) {
//             $aGoodIds[] = $v1->link_id;
//         }
//
//         foreach ($aPackage as $v2) {
//             $aPackageIds[] = $v2->link_id;
//         }
//
//         $aGoodIds    = array_unique($aGoodIds);
//         $aGoodIds    = array_values($aGoodIds);
//         $aPackageIds = array_unique($aPackageIds);
//         $aPackageIds = array_values($aPackageIds);
//
//         $aGoodShop = DB::table('goods')->whereIn('id', $aGoodIds)->get(['id','shop_id'])->toArray();
//         $aGoodShop = array_column($aGoodShop, 'shop_id', 'id');// key:good_id,  value:shop_id
//
//         $aPackageShop = DB::table('good_packages')->whereIn('id', $aPackageIds)->get(['id','shop_id'])->toArray();
//         $aPackageShop = array_column($aPackageShop, 'shop_id', 'id');// key:package_id,  value:shop_id
//
//
//         foreach ($aGood as $vv) {
//             $shop_id = isset($aGoodShop[$vv->link_id]) ? $aGoodShop[$vv->link_id] : 0;
//             DB::table('comments')->where('id', $vv->id)->update(['shop_id' => $shop_id]);
//         }
//
//         foreach ($aPackage as $vv) {
//             $shop_id = isset($aPackageShop[$vv->link_id]) ? $aPackageShop[$vv->link_id] : 0;
//             DB::table('comments')->where('id', $vv->id)->update(['shop_id' => $shop_id]);
//         }


        $this->validate($request, [
            'shop_id' => 'required|integer',//门店id
            'offset'  => 'nullable|integer',
            'count'   => 'nullable|integer',
        ]);

        $shop_id = (int)$request->input('shop_id');
        $offset  = (int)$request->input('offset');
        $count   = (int)$request->input('count');

        $comment = Comment::query()
                    ->leftJoin('users AS u', 'comments.user_id', '=', 'u.id')
                    ->where('comments.shop_id', $shop_id)
                    ->where('is_show', 1)
                    ->where('is_delete', 0)
                    ->orderBy('comments.created_at', 'desc');

        $data = $comment
                    ->offset($offset)
                    ->limit($count)
                    ->get(['comments.*', 'u.avatar', 'u.nickname']);

        // 商家回复
        $aCommentChild = Comment::query()
            ->whereIn('pid', $data->pluck('id')->all())
            ->get(['id','pid','content'])
            ->keyBy('pid');

        $re = $data->map(function ($item) use ($aCommentChild) {
            if (!empty($item->image)) {
                $tmp = [];
                foreach ($item->image as $value) {
                    $tmp[] = OSS::instance()->getUrl($value);
                }
                $item->image = $tmp;
            }

            return [
                'id'               => $item->id,
                'score'            => $item->score,
                'nickname'         => $item->nickname,
                'avatar'           => $item->avatar,
                'content'          => $item->content ?? "没有评价内容",
                'image'            => $item->image,
                'created_at'       => $item->created_at->toDateTimeString(),
                'child'            => !empty($aCommentChild->get($item->id)) ? $aCommentChild->get($item->id) : (!empty($item->system_reply) ? ['content' => $item->system_reply, 'system_responder' => $item->system_responder] : ''),
                'system_reply'     => $item->system_reply,
                'system_responder' => $item->system_responder,
            ];
        });

        return $this->success($re);
    }


}
